from sentinelsat import SentinelAPI
from queue import Queue
import multiprocessing
import psycopg2
import datetime
import re
import os

account_infos = [
		["fyy001", "show1234"],
		["fyy_01", "show1234"],
		["fyy_02", "show1234"],
		["fyy_03", "show1234"],
		["fyy_04", "show1234"],
		["wyq01", "show970213"],
		["wyq02", "show970213"],
		["wyq03", "show970213"],
		["wyq04", "show970213"],
		["wyq05", "show970213"],
		["wyq06", "show970213"],
		["wyq07", "show970213"],
		["hxx2021", "hxx2021123"],
		["hxx2022", "hxx2022123"],
		["hxx20221", "hxx2022123"],
		["hxx20222", "hxx20222123"],
	]
account_count = len(account_infos)
account_queue = Queue(maxsize=account_count)
for i in range(account_count):
	account_queue.put(i,block=True)

# 清临时数据
def delete_incomplete(args):
	[tiles, start_date, end_date, save_folder] = args
	start_date = datetime.datetime.strptime(start_date,"%Y-%m-%d")
	end_date = datetime.datetime.strptime(end_date,"%Y-%m-%d")
	temp_date = start_date
	dates = []
	while temp_date < (end_date+datetime.timedelta(days=1)):
		dates.append(temp_date.strftime("%Y%m%d"))
		temp_date = temp_date + datetime.timedelta(days=1)
	datestr = "|".join(dates)
	tilestr = "|".join(tiles)
	name_re = f"^S2.*_({datestr})T.*_T({tilestr})_.*\.zip\.incomplete$"
	for name in os.listdir(save_folder):
		if re.match(name_re,name):
			os.remove(os.path.join(save_folder, name))
	return

# download sentinel2 data
def sentinel2_downloader(args):
	[username,password,tile,start_date,end_date,max_cloud,directory_path]=args
	start_date=datetime.datetime.strptime(start_date,"%Y-%m-%d")
	end_date=datetime.datetime.strptime(f"{end_date} 23:59:59","%Y-%m-%d %H:%M:%S")
	# api_url='https://scihub.copernicus.eu/apihub/' # 无法下载历史数据
	api_url='https://scihub.copernicus.eu/dhus/'
	api = SentinelAPI(
		username,
		password,
		api_url,
		show_progressbars=True,
		timeout=10*60
	)
	query_kwargs = {
		'platformname': 'Sentinel-2',
		'producttype': 'S2MSI1C',
		'date': (start_date, end_date),
		'cloudcoverpercentage': (0, max_cloud),
		'tileid': tile,
		'raw': f'tileid:{tile} OR filename:*_T{tile}_*'
	}
	product_ids=api.query(**query_kwargs)
	api.download_all(
		product_ids,
		directory_path=directory_path,
		max_attempts=10,  # 尝试下载次数
		checksum=True,
		n_concurrent_dl=4  # 单个账号只允许最多四个并发流	
	)
	return

# get sentinel2 tile list
def get_province_tiles(province):
	con = psycopg2.connect(
	database="sentinel2",
	user="postgres",
	password="12345",
	host="192.168.2.172",
	port="5432"
	)
	cur = con.cursor()
	sql = f"""
		SELECT "中国有效哨兵格网分布wgs84".mgrs
		FROM china_sy
		JOIN "中国有效哨兵格网分布wgs84" 
		on st_intersects(china_sy.geom,"中国有效哨兵格网分布wgs84".geom)
		WHERE  china_sy.qhmc = '{province}' 
	"""
	cur.execute(sql)
	con.commit()
	tiles=[record[0] for record in cur.fetchall()]
	tiles = [tile.upper() for tile in tiles]
	cur.close()
	con.close()
	return tiles

# get sentinel2 tile list
def get_city_tiles(province, city):
    con = psycopg2.connect(
    database="sentinel2",
    user="postgres",
    password="12345",
    host="192.168.2.172",
    port="5432"
    )
    cur = con.cursor()
    sql = f"""
    SELECT "中国有效哨兵格网分布wgs84".mgrs
    FROM china_dsy
    JOIN "中国有效哨兵格网分布wgs84" 
    on st_intersects(china_dsy.geom,"中国有效哨兵格网分布wgs84".geom)
    WHERE  china_dsy.qhmc = '{city}' 
    AND sjxzqdm in (
        SELECT qhdm
        FROM china_sy
        WHERE  china_sy.qhmc = '{province}' 
    )
    """
    cur.execute(sql)
    con.commit()
    tiles=[record[0] for record in cur.fetchall()]
    tiles = [tile.upper() for tile in tiles]
    cur.close()
    con.close()
    return tiles

# get sentinel2 tile list
def get_county_tiles(province, city, county):
    con = psycopg2.connect(
    database="sentinel2",
    user="postgres",
    password="12345",
    host="192.168.2.172",
    port="5432"
    )
    cur = con.cursor()
    sql = f"""
    SELECT "中国有效哨兵格网分布wgs84".mgrs
    FROM china_xy
    JOIN "中国有效哨兵格网分布wgs84" 
    on st_intersects(china_xy.geom,"中国有效哨兵格网分布wgs84".geom)
    WHERE  china_xy.qhmc = '{county}' 
    AND sjxzqdm in (
        SELECT qhdm
        FROM china_dsy
        WHERE qhmc = '{city}'
        AND sjxzqdm in (
            SELECT qhdm
            FROM china_sy
            WHERE china_sy.qhmc = '{province}'
        )  
    )
    """
    cur.execute(sql)
    con.commit()
    tiles=[record[0] for record in cur.fetchall()]
    tiles = [tile.upper() for tile in tiles]
    cur.close()
    con.close()
    return tiles

# 启动下载
def main():
	os.system(r"net use Z: \\192.168.2.172\root DELL123dell /user:root /PERSISTENT:YES")

	province = "河南省"
	start_date,end_date="2020-12-1","2020-12-31"
	max_cloud=100
	directory_path = r"E:\dataset"

	# province = "河南省"
	start_date,end_date="2021-6-1","2021-6-30"
	max_cloud=100
	directory_path = r"E:\河南202106"

	# directory_path = r"Z:\新疆202205"
	accounts = [
		["hxx2021", "hxx2021123"],
		["hxx2022", "hxx2022123"],
		["hxx20221", "hxx2022123"],
		["hxx20222", "hxx20222123"],
	]
	# tiles = get_province_tiles(province)

	# tiles = r"50SLD-50SMD-50SKC-50SLC"
	# tiles = r"44TPP-44TMP-44TNP-44TQP-44TMN-44TNN-44TPN-44TPM-44TQM-46TEP-45TUJ-45TVJ-45TWJ-45TXJ-46TEN-45TYJ-45TXH-45TWG-45TYH-45TUG-45TVG-46TCP-45TTG"
	# tiles = r"43SED-43SFD-43SGD-43SFC-43SGC-44SKJ-44SKG-44SLG-44SMG-44SNF-44TLL-44TML-44TNL-44TPL-44TQL-44TLK-44TMK-44TNK-45SUC-45TTF-45TUF-45TVF-45TWF-44SLJ"
	# tiles = r"44TPS-44TQS-44TPR-44TPQ-44TQR-44TMQ-44TNQ-44TQQ-45TXM-45TVK-45TWK-45TXK-45TVN-45TWN-45TXN-45TYN-45TVM-45TWM-45TYM-45TUL-45TUK-45UVP-46TCS"
	# tiles = tiles.split("-")

	tiles = r"50SLD-50SMD-50SKC-50SLC"
	# tiles = r"44TPP-44TMP-44TNP-44TQP-44TMN-44TNN-44TPN-44TPM-44TQM-46TEP-45TUJ-45TVJ-45TWJ-45TXJ-46TEN-45TYJ-45TXH-45TWG-45TYH-45TUG-45TVG-46TCP-45TTG"
	# tiles = r"43SED-43SFD-43SGD-43SFC-43SGC-44SKJ-44SKG-44SLG-44SMG-44SNF-44TLL-44TML-44TNL-44TPL-44TQL-44TLK-44TMK-44TNK-45SUC-45TTF-45TUF-45TVF-45TWF-44SLJ"
	# tiles = r"44TPS-44TQS-44TPR-44TPQ-44TQR-44TMQ-44TNQ-44TQQ-45TXM-45TVK-45TWK-45TXK-45TVN-45TWN-45TXN-45TYN-45TVM-45TWM-45TYM-45TUL-45TUK-45UVP-46TCS"
	tiles = tiles.split("-")

	delete_incomplete([tiles, start_date, end_date, directory_path])
	for i in range(0,len(tiles),len(accounts)):
		if len(accounts)+i>len(tiles):
			temp = tiles[i:len(tiles)]
		else:
			temp = tiles[i:len(accounts)+i]
		processings = []
		for tile,[username, password] in zip(temp,accounts):
			args = [username,password,tile,start_date,end_date,max_cloud,directory_path]
			processing = multiprocessing.Process(target=sentinel2_downloader, args=(args,))
			processings.append(processing)
		for processing in processings:
			processing.start() #启动进程p
		for processing in processings:
			processing.join() #等待进程p终止
	return
	

if __name__ == "__main__":
	main()
	